package org.dant.ant.extension.net.socket;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;

import org.dant.ant.extension.net.DefaultDispatcher;
import org.dant.ant.extension.net.Dispatcher;
import org.dant.ant.extension.net.NetConstants;
import org.dant.ant.extension.tasks.internal.Endpoint;
import org.dant.ant.extension.tasks.internal.RemoteCommand;
import org.dant.ant.extension.tasks.internal.RemoteResponse;

public class SocketServer {

    protected Endpoint ep = new Endpoint();
    protected Dispatcher dispatcher = new DefaultDispatcher();
    protected ByteBuffer objBuffer = ByteBuffer.allocate(1024);
  
    public SocketServer() throws Exception {
        this(NetConstants.DEFAULT_SOCKET_PORT);
    }
  
    public SocketServer(int port) throws Exception {
        ep.setPort(port + "");
        ep.setProtocol(NetConstants.SOCKET_PROTOCOL);
        acceptConnections(port);
    }
  
    public static void main(String[] args) throws Exception {
        try {
            if (args.length < 1) {
                new SocketServer();
            } else {
                new SocketServer(Integer.parseInt(args[0]));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  
    private String getFullURL() {
        return ep.getFullURL();
    }
  
    private void acceptConnections(int port) throws Exception {
        ServerSocket server_socket = new ServerSocket(port);
        System.out.println("Running on port " + getFullURL());
    
        while(true) {
            Socket socket = server_socket.accept();
            System.out.println("New connection accepted " + socket.getInetAddress()
                               + ":" + socket.getPort());
            ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

            RemoteCommand request = (RemoteCommand) input.readObject();
      
            RemoteResponse response = new RemoteResponse();
            response.setFullURL(getFullURL());
            dispatcher.dispatch(request, response);
      
            output.writeObject(response);
            output.flush();
            System.out.println("Response send out");
      
            try {
                socket.close();
                output.close();
                input.close();
                System.out.println("Connection closed by client");
            } catch (IOException e) {
                System.out.println(e);
            }
        }
    }
}
